//
//  UserMigration.swift
//  hello
//
//  Created by 赵康 on 2024/11/11.
//
import Fluent
import Vapor

extension User {
	struct Migration: AsyncMigration {
		var name: String { "UserMigration" }
		
		func prepare(on database: any Database) async throws {
			try await database.schema(User.schema)
				.id()
				.field(User.FieldKeys.name, .string, .required)
				.field(User.FieldKeys.email, .string, .required)
				.field(User.FieldKeys.password, .string, .required)
				.field(User.FieldKeys.avatar, .string)
				.field(User.FieldKeys.phone, .string)
				.field(User.FieldKeys.bio, .sql(.text))
				.field(User.FieldKeys.isDeleted, .bool, .required, .sql(.default(false)))
				.field(User.FieldKeys.createdAt, .datetime, .required)
				.field(User.FieldKeys.updatedAt, .datetime, .required)
				.field(User.FieldKeys.isEmailVerified, .bool, .required, .sql(.default(false)))
				.field(User.FieldKeys.isPhoneVerified, .bool, .required, .sql(.default(false)))
				.field(User.FieldKeys.isSubscribed, .bool, .required, .sql(.default(false)))
				.unique(on: User.FieldKeys.email)
				.unique(on: User.FieldKeys.phone)
				.create()
		}
		
		func revert(on database: any Database) async throws {
			try await database.schema(User.schema).delete()
		}
	}
}

extension User {
  struct AddCurrentStreakField : AsyncMigration {
    var name: String { "AddCurrentStreakField" }
    func prepare(on database: any Database) async throws {
      try await database.schema(User.schema)
        .field(User.FieldKeys.currentStreak, .int, .required, .sql(.default(0)))
        .update()
    }
    
    func revert(on database: any Database) async throws {
      try await database.schema(User.schema)
        .deleteField(User.FieldKeys.currentStreak)
        .update()
    }
  }
}

extension User {
  struct AddDailyGoalField : AsyncMigration {
    var name: String { "AddDailyGoalField" }
    func prepare(on database: any Database) async throws {
      try await database.schema(User.schema)
        .field(User.FieldKeys.dailyGoal, .double, .required, .sql(.default(600)))
        .update()
    }
    
    func revert(on database: any Database) async throws {
      try await database.schema(User.schema)
        .deleteField(User.FieldKeys.dailyGoal)
        .update()
    }
  }
}

extension User {
  struct AddPointsSystemFields : AsyncMigration {
    var name: String { "AddPointsSystemFields" }
    func prepare(on database: any Database) async throws {
      try await database.schema(User.schema)
        .field(User.FieldKeys.points, .int, .required, .sql(.default(0)))
        .field(User.FieldKeys.lastPointsAwardedDate, .datetime)
        .field(User.FieldKeys.totalCheckIns, .int, .required, .sql(.default(0)))
        .field(User.FieldKeys.lastMilestoneAwarded, .int, .required, .sql(.default(0)))
        .update()
    }
    
    func revert(on database: any Database) async throws {
      try await database.schema(User.schema)
        .deleteField(User.FieldKeys.points)
        .deleteField(User.FieldKeys.lastPointsAwardedDate)
        .deleteField(User.FieldKeys.totalCheckIns)
        .deleteField(User.FieldKeys.lastMilestoneAwarded)
        .update()
    }
  }
}

extension User {
  struct AddTermsFields : AsyncMigration {
    var name: String { "AddTermsFields" }
    func prepare(on database: any Database) async throws {
      try await database.schema(User.schema)
        .field(User.FieldKeys.termsAccepted, .bool, .required, .sql(.default(false)))
        .field(User.FieldKeys.termsAcceptedAt, .datetime)
        .field(User.FieldKeys.termsVersion, .string)
        .update()
    }
    
    func revert(on database: any Database) async throws {
      try await database.schema(User.schema)
        .deleteField(User.FieldKeys.termsAccepted)
        .deleteField(User.FieldKeys.termsAcceptedAt)
        .deleteField(User.FieldKeys.termsVersion)
        .update()
    }
  }
}
